// 几张卡牌 排成一行，每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。
// 每次行动，你可以从行的开头或者末尾拿一张卡牌，最终你必须正好拿 k 张卡牌。
// 你的点数就是你拿到手中的所有卡牌的点数之和。

// 给你一个整数数组 cardPoints 和整数 k，请你返回可以获得的最大点数。


const maxScore = function (cardPoints: number[], k: number): number {
    let totalSum = 0;
    // 计算数组总和
    for (let i = 0; i < cardPoints.length; i++) {
        totalSum += cardPoints[i];
    }
    // 初始化窗口和
    let windowSum = 0;
    for (let i = 0; i < cardPoints.length - k; i++) {
        windowSum += cardPoints[i];
    }
    let res = totalSum - windowSum;// 结果变量
    // 初始化窗口变量
    let left = 0;
    let right = cardPoints.length - k;
    // 滑动窗口过程
    while (right < cardPoints.length) {
        windowSum -= cardPoints[left];
        windowSum += cardPoints[right];
        res = Math.max(res, totalSum - windowSum);
        left++;
        right++;
    }
    return res;
};


// 这道题目如果巧妙地想到了可以使用滑动窗口求解的话其实难度就不大了
// 关键还是要善于厘清题意
// 已知数组的长度，由于只能从开头和末尾拿 k 张卡牌，所以最后拿完牌剩下的必然是连续的 n-k 张卡牌
// 所以变相来说我们可以通过求出剩余卡牌点数之和的最小值，来求出拿走卡牌点数之和的最大值。
// 而由于剩余卡牌是连续的，可以想到使用一个固定长度为 n-k 的滑动窗口
// 对数组进行遍历，求出滑动窗口最小值，
// 然后用所有卡牌的点数之和减去该最小值，即可维护出了拿走卡牌点数之和的最大值。
